/**
 * webSocket 链接方法
 * STOMP 是基于 WebSocket（SockJS）的上层协议
 * @Author: yam
 * @Date: 2021-03-31
 * @LastEditors: yam
 * @LastEditTime: 2021-03-31
*/
import {
    SocketURL
} from './baseurl.js';
let socketUrl = SocketURL
var Stomp = require('../../utils/stomp.js').Stomp;
// socket是否连接
var socketConnected = false;
// 待发送的消息队列
var messageQueue = [];
// 是否断线重连
var reconnect = true;
// 断线重连次数
var reconnectnum = 0;
var stompClient = '';
var stompClientArr = [];

let initData = (res) => {
    socketConnected = false;
    messageQueue = [];
    reconnect = true;
    reconnectnum = 0;
    stompClient = '';
}

let currentPage 


let isIphone = () => {
    let status
    wx.getSystemInfo({
        success: res => {
            if (res.model.search('iPhone') != -1) {
                return status = true
            } else {
                return status = false
            }
        }
    })
    return status
}

// 发送消息
let sendSocketMessage = (msg) => {
    // 如果socket已连接则发送消息
    if (socketConnected) {
        wx.sendSocketMessage({
            data: msg
        })
    } else {
        // socket没有连接将消息放入队列中
        messageQueue.push(msg);
    }
}

/**
 * 关闭连接
 * 必须在WebSocket打开期间调用wx.closeSocket才能关闭
 **/
let close = () => {
    if (socketConnected) {
        wx.closeSocket()
        socketConnected = false
    }
}

/**
 * 创建一个 WebSocket 连接
 * api.RTCWSSHOST_URL,你的wss链接
 * token ；与服务端定义的参数
 * page  页面  getSocketIndex页面的方法（缓存的socket  下标）
 **/
let connect = (obj, page) => {
    currentPage = page
    // var token = 'token = '+ wx.getStorageSync('clienttoken')
    wx.connectSocket({
        // url: api.RTCWSSHOST_URL + ' ? token = '+wx.getStorageSync('clienttoken'),
        // url:`${socketUrl}?userId=` + obj.userId + "&client=" + obj.client,
        url: obj.url,
        success: res => {
            // console.log('connectSocket 连接成功', res)
            page.getSocketIndex && page.getSocketIndex(stompClientArr.length)
        },
        fail: err => {
            console.error(err, '连接失败')
        }
    })
}

/**
 * 关闭指定长连接
 * 加wx.closeSocket() 解决 wx.onSocketOpen 有时候无法触发的问题
 **/
let closeSocket = (index) => {
    if (index > 0 && socketConnected) {
        stompClientArr[index - 1].disconnect() //关闭前一个链接
        if (stompClientArr[index - 1].connected) {
            wx.closeSocket()
        }
        reconnect = false //手动关闭，断线不重连
        socketConnected = false
    } else if (index == 0 ) {
        wx.closeSocket()
        socketConnected = false
        reconnect = false //手动关闭，断线不重连
    }
}

/*
 * params , 参数
 * page , 页面标识，区分不同页面打开的websocket
 * pageFun , 页面回到函数，传参用
 * type  , 标识广播订阅类型
 */
let initSocket = (params, page, type) => {
    var userId = params.userId;
    var obj = {
        'uuid': params.uuid, // uuid
        'userId': userId,
        'client': 'MOBILE', // MOBILE移动端， pc电脑端
        'url': `${socketUrl}?userId=` + userId + "&client=" + 'MOBILE'
    };

    // 符合WebSocket定义的对象
    var ws = {
        send: sendSocketMessage,
        close: close
    }

    // 创建一个 WebSocket 连接
    connect(obj, page);

    // 监听 WebSocket 连接打开事件
    // reconnect = true;        
    // 连上，默认断线重连
    wx.onSocketOpen(function (res) {
       // console.log(res, '监听 WebSocket 连接打开事件,WebSocket 连接成功')
        socketConnected = true;
        reconnect = true;
        ws.onopen();
        page.onSocketConnectStatus && page.onSocketConnectStatus(true)
    })

    // 监听 WebSocket 接受到服务器的消息事件
    wx.onSocketMessage(function (res) {
        // if (res.data.indexOf('CONNECTED') > -1 && isIphone()) {
        //     console.log('CONNECTED')
        // } else if (res.data.indexOf('MESSAGE') > -1 && isIphone()) {
        //     let Byte = {
        //         LF: '\x0A',
        //         NULL: '\x00'
        //     };
        //     let msgBody = res.data.split(RegExp("" + Byte.NULL + Byte.LF + "*"))[0],
        //         msgStr = `{"content":${msgBody.split('{"content":')[1]}`;
        //     var data = JSON.parse(msgStr).content;
        //     console.log(data, 'MESSAGE')
        //     let type = JSON.parse(data).type
        //     if(type == 'UPLOAD_SNAPSHOT'){
        //         page.callBackSocket(data, '')
        //     }else {
        //         page.callBackSocket('', data)
        //     }
        // }
        if (res.data.indexOf('CONNECTED') > -1 ) {
                // console.log('CONNECTED')
        } else if (res.data.indexOf('"messageType":"TOPIC"') > -1) {
            let Byte = {
                LF: '\x0A',
                NULL: '\x00'
            };
            let msgBody = res.data.split(RegExp("" + Byte.NULL + Byte.LF + "*"))[0],
                msgStr = `${msgBody.split('{"messageType":"TOPIC","content":')[1]}`;
                msgStr =  `{"content":${msgStr}`
            var data = JSON.parse(msgStr).content;  
            console.log( data  ,  'wx.onSocketMessage  TOPIC' )
            page.callBackSocket && page.callBackSocket('', data)
        } else if (res.data.indexOf('"messageType":"P2P"') > -1) {
            let Byte = {
                LF: '\x0A',
                NULL: '\x00'
            };
            let msgBody = res.data.split(RegExp("" + Byte.NULL + Byte.LF + "*"))[0],
                msgStr = `${msgBody.split('{"messageType":"P2P","content":')[1]}`;
                msgStr =  `{"content":${msgStr}`
            var data = JSON.parse(msgStr).content;  
            console.log( data  ,  'wx.onSocketMessage  P2P' )
            page.callBackSocket && page.callBackSocket(data, '')
        } 
        ws.onmessage(res, '接受到服务器的消息事件');
    })

    //  监听 WebSocket 错误事件
    //  断线重连5次后，1分钟之后重连
    wx.onSocketError(function (res) {
        console.log(res, 'WebSocket 错误')
        socketConnected = false;
        page.onSocketConnectStatus && page.onSocketConnectStatus(false)
        if (reconnect) {
            let timer 
            if (reconnectnum < 10) {
              timer = setTimeout(() => {
                  reconnectnum += 1;
                  connect(obj, page);
                }, 1000)
              reconnectnum += 1;
            } else if (reconnectnum < 20) {
              timer = setTimeout(() => {
                reconnectnum += 1;
                connect(obj, page);
              }, 5000)
              reconnectnum += 1;
            } else {
                timer = setTimeout(() => {
                    reconnectnum = 0;
                    stompClient.disconnect();
                    connect(obj, page);
                }, 60000)
                reconnectnum += 1;
            }
            // if (reconnectnum > 5) {
            //     setTimeout(function () {
            //         reconnectnum = 0;
            //         stompClient.disconnect();
            //         connect(obj, page);
            //     }, 60000);
            // } else {
            //     setTimeout(()=>{
            //         reconnectnum += 1;
            //         connect(obj, page);
            //    },1000)
            // }
        }
    })
     
    /**
     * 监听 WebSocket 连接关闭事件
     * 断线重连5次后，1分钟之后重连  10*60
     * 连的频率越来越慢
     **/
    wx.onSocketClose(function (res) {
        console.log(res, 'WebSocket 连接关闭')
        socketConnected = false;
        page.onSocketConnectStatus && page.onSocketConnectStatus(false)
        if (reconnect) {
            let timer 
            if (reconnectnum < 10) {
              timer = setTimeout(() => {
                  reconnectnum += 1;
                  connect(obj, page);
                }, 1000)
              reconnectnum += 1;
            } else if (reconnectnum < 20) {
              timer = setTimeout(() => {
                reconnectnum += 1;
                connect(obj, page);
              }, 5000)
              reconnectnum += 1;
            } else {
                timer = setTimeout(() => {
                    reconnectnum = 0;
                    stompClient.disconnect();
                    connect(obj, page);
                }, 60000)
                reconnectnum += 1;
            }
        }
        // if (reconnect) {
        //    // console.log('断线重连 ** ** ** ** ** ** ** * ')
        //     if (reconnectnum > 5) {
        //         setTimeout(function () {
        //             reconnectnum = 0;
        //             stompClient.disconnect();
        //             connect(obj, page);
        //         }, 60000);
        //     } else {
        //        setTimeout(()=>{
        //             reconnectnum += 1;
        //             connect(obj, page);
        //        },1000)
        //     }
        // }
    })

    /**
     * 定期发送心跳或检测服务器心跳;
     * 可看stomp.js的源码（195,207，489行），由于小程序没有window对象，
     * 所以我们要调用小程序的定时器api实现
     */
    Stomp.setInterval = function (interval, f) {
        return setInterval(f, interval);
    };

    // 结束定时器的循环调用
    Stomp.clearInterval = function (id) {
        return clearInterval(id);
    };

    stompClient = Stomp.over(ws);
    stompClientArr.push(stompClient) //缓存

    stompClient.connect({
        // 'clienttype': '小程序'
    }, function (callback) {

        // 接收一对一的推送消息,
        //其中userId由服务端传递过来,
        //用于表示唯一的用户,通过此值将消息精确推送给一个用户
        stompClient.subscribe('/user/' + obj.client + ':' + obj.userId + '/msg', function (res) {
            // 收到消息时的回调方法。
            // console.log(JSON.parse(res.body), '接收一对一的推送消息')
            var data = JSON.parse(res.body).content
            page.callBackSocket && page.callBackSocket(data, '')
           
        });

        // 接收广播
        stompClient.subscribe('/topic/response/' + obj.uuid, function (res) {
            // 收到消息时的回调方法。
            // console.log(JSON.parse(res.body), '接收广播消息时的回调方法')
            var data = JSON.parse(res.body).content
            page.callBackSocket && page.callBackSocket('', data)
        });
    }, function (err) {
        // console.log('err',err)
    })
}

module.exports = {
    initSocket,
    closeSocket,
}
